package com.hotel.front;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.SharedCache;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.labs.repackaged.org.json.JSONException;
import com.google.gson.Gson;
import com.hotel.BL.CounterLogic;
import com.hotel.BL.GenericLogic;
import com.hotel.BL.LoginLogic;
import com.hotel.BL.POSLogic;
import com.hotel.BL.UserLogic;
import com.hotel.BL.UserMappingHotelLogic;

import data.Counter;
import data.General;
import data.LoginData;
import data.POS;
import data.User;
import data.UserMappingHotel;

@SuppressWarnings("serial")
public class LoginService extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		try{
			String doClass = req.getParameter("func");
			if(doClass.equals("login")){
				Login(req,resp);
			}else if(doClass.equals("continuelogin")){
				ContinueLogin(req,resp);
			}else if(doClass.equals("updateCounter")){
				UpdateCounter(req,resp);
			}else if(doClass.equals("getlogin")){
				Getlogin(req,resp);
			}else if(doClass.equals("logout")){
				Logout(req,resp);
			}else if(doClass.equals("logoutById")){
				LogoutById(req,resp);
			}else if(doClass.equals("editStatusLoggedIn")){
				ChangeStatusLoggedIn(req,resp);
			}else if(doClass.equals("loadCounter")){
				LoadCounter(req,resp);
			}else if(doClass.equals("loadWorkArea")){
				LoadWorkArea(req,resp);
			}else if(doClass.equals("loadDataAndCounter")){
				LoadDataAndCounter(req,resp);
			}else if(doClass.equals("loadDataAndWorkArea")){
				LoadDataAndWorkArea(req,resp);
			}else if(doClass.equals("saveSessionAndLoadCounter")){
				SaveSessionAndLoadCounter(req,resp);
			}else if(doClass.equals("deleteSession")){
				DeleteSession(req,resp);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	private void Login(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		String hotelIdL = req.getParameter("hotelIdL");
		String hotelIdS = req.getParameter("hotelIdS");
		String email = req.getParameter("email");
		String pass = req.getParameter("pass");
		HttpSession session=req.getSession(true);
		HashMap<String, Object> hash = new LoginLogic(req,resp).Login(hotelIdL, hotelIdS, email, pass,session.getId());
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		LoginData obj = (LoginData) hash.get("userData");
		boolean checksession = (Boolean) hash.get("checksession");
		boolean intime = (Boolean) hash.get("intime");
		hashresult.put("checksession", checksession);
		hashresult.put("intime", intime);

		if(obj != null)
		{
			obj.setWorkAreaAmount(Long.parseLong(String.valueOf(hash.get("workAreaAmount"))));
			
			session.setAttribute("hotelIdL", hotelIdL);
			session.setAttribute("hotelIdS", hotelIdS);
			session.setAttribute("email", email);
			session.setAttribute("pass", pass);
			
			if((intime != true && checksession != false) || (intime == false && checksession == false) || (intime == true && checksession == true)){
			//	session.setMaxInactiveInterval(10);	
				General general = new GenericLogic(req,resp).GetGeneral(obj.getHotelId());
				session.setAttribute("hotelId", obj.getHotelId());
				session.setAttribute("symbol", general.getDefaultCurrency().getSymbol());
				session.setAttribute("is24", new GenericLogic(req,resp).GetGeneral(obj.getHotelId()).isTimeFormatShow24Hours());
				session.setAttribute("LanguageCode", obj.getDefaultLanguage().getLanguageCode());
				session.setAttribute("LanguageSubcode", obj.getDefaultLanguage().getLanguageSubCode());
				String name = obj.getUser().getFirstName();
				if(obj.getUser().getLastName() != null && !obj.getUser().getLastName().isEmpty())
					name = name + " " + obj.getUser().getLastName();
				session.setAttribute("user", name );
				session.setAttribute("userid", obj.getUser().getId() );
				session.setAttribute("userEmail", obj.getUser().getEmail());
				session.setAttribute("isIncludetax",general.isIncloudetax());
				session.setAttribute("GMT",general.getGMT());
				session.setAttribute("NightAuditTime", general.getNightAuditTime());
				session.setAttribute("MinuteForWarning", general.getMinuteForWarning());
				session.setAttribute("MinuteForCritical", general.getMinuteForCritical());
				
				User u = new UserLogic(req,resp).GetUser(obj.getUser().getId());
				u.setSessionid(session.getId());
				new UserLogic(req,resp).UpdateUser(u);
				SharedCache.setSharedCache("LoginLogic.GetUser."+obj.getUser().getId(),u,86400);
				User result = new User();
				result.setEntity(u.getEntity());
				
				session.removeAttribute("hotelIdL");
				session.removeAttribute("hotelIdS");
				session.removeAttribute("email");
				session.removeAttribute("pass");
				UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(obj.getHotelId(), String.valueOf(obj.getUser().getId()));
				int WAsize = s1.getUserlevel().getWorkAreas().size();
				boolean adminAllowed = s1.getUserlevel().isAdminAllowed();
				boolean housekeepingAllowed = s1.getUserlevel().isHousekeepingAllowed();
				if(WAsize == 1 && !adminAllowed && !housekeepingAllowed){
					if(s1.getUserlevel().getDefaultWorkAreas().getTitle().equals("iFront")){
						session.setAttribute("pageType","F");
					}else{
						session.setAttribute("pageType","P");
					}
					session.setAttribute("workArea",Long.parseLong(s1.getUserlevel().getDefaultWorkAreasString()));	
				}else if(WAsize == 0 && adminAllowed && !housekeepingAllowed){
					session.setAttribute("pageType","A");
					session.setAttribute("workArea",Long.parseLong(s1.getUserlevel().getDefaultWorkAreasString()));	
				}else if(WAsize == 0 && !adminAllowed && housekeepingAllowed){
					session.setAttribute("pageType","H");
					session.setAttribute("workArea",Long.parseLong(s1.getUserlevel().getDefaultWorkAreasString()));	
				}
			}
			hashresult.put("data", obj);
			hashresult.put("servertime", new GenericLogic(req,resp).ServerDateTime(obj.getHotelId()));
			hashresult.put("Full", hotelIdL);
		}else{
			hashresult.put("data", null);
		}
		
		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}

	private void ContinueLogin(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		HttpSession session=req.getSession(true);

		String hotelIdL = (String)session.getAttribute("hotelIdL");
		String hotelIdS = (String)session.getAttribute("hotelIdS");
		String email = (String)session.getAttribute("email");
		String pass = (String)session.getAttribute("pass");

		HashMap<String, Object> hash = new LoginLogic(req,resp).Login(hotelIdL, hotelIdS, email, pass,session.getId());
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		LoginData obj = (LoginData) hash.get("userData");
		hashresult.put("checksession", true);
		hashresult.put("intime", false);

		General general = new GenericLogic(req,resp).GetGeneral(obj.getHotelId());
		session.setAttribute("hotelId", obj.getHotelId());
		session.setAttribute("LanguageCode", obj.getDefaultLanguage().getLanguageCode());
		session.setAttribute("LanguageSubcode", obj.getDefaultLanguage().getLanguageSubCode());
		String name = obj.getUser().getFirstName();
		if(obj.getUser().getLastName() != null && !obj.getUser().getLastName().isEmpty())
			name = name + " " + obj.getUser().getLastName();
		session.setAttribute("user", name );
		session.setAttribute("userid", obj.getUser().getId() );
		session.setAttribute("isIncludetax",general.isIncloudetax());
		session.setAttribute("GMT",general.getGMT());
		session.setAttribute("NightAuditTime", general.getNightAuditTime());
		session.setAttribute("MinuteForWarning", general.getMinuteForWarning());
		session.setAttribute("MinuteForCritical", general.getMinuteForCritical());

		User u = new UserLogic(req,resp).GetUser(obj.getUser().getId());
		u.setSessionid(session.getId());
		new UserLogic(req,resp).UpdateUser(u);
		SharedCache.setSharedCache("LoginLogic.GetUser."+obj.getUser().getId(),u,86400);
		User result = new User();
		result.setEntity(u.getEntity());
		
		session.removeAttribute("hotelIdL");
		session.removeAttribute("hotelIdS");
		session.removeAttribute("email");
		session.removeAttribute("pass");

		UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(obj.getHotelId(), String.valueOf(obj.getUser().getId()));
		if(s1.getUserlevel().getWorkAreas().size() == 1){
			session.setAttribute("workArea",Long.parseLong(s1.getUserlevel().getDefaultWorkAreasString()));					
		}

		hashresult.put("data", obj);
		hashresult.put("servertime", new GenericLogic(req,resp).ServerDateTime(obj.getHotelId()));
		
		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}

	private void LoadCounter(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		HttpSession session=req.getSession(true);
		
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userid = (Long)session.getAttribute("userid");
		
		UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(hotelId, String.valueOf(userid));
		String defaultCounter = s1.getUserlevel().getDefaultWorkAreas().getDefaultCounterString();
		List<Counter> counterList = new CounterLogic().GetAllCounter(hotelId);
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		
		hashresult.put("data", counterList);
		hashresult.put("defaultCounter", defaultCounter);

		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}

	void UpdateCounter(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException, EntityNotFoundException
	{	
		HttpSession session=req.getSession(true);
		long hotelId = (Long) session.getAttribute("hotelId");
		String currentCounter = req.getParameter("currentCounter");
		session.setAttribute("currentCounter", currentCounter);
		session.setAttribute("counter", Long.parseLong(currentCounter));
		long userId = (Long) session.getAttribute("userid");
		new LoginLogic(req,resp).SetCounter(hotelId,userId,currentCounter);
		CounterLogic counterLogic = new CounterLogic();
		Counter counter = counterLogic.GetCounter(Long.parseLong(currentCounter));
		counter.setLastUserString(String.valueOf(userId));
		counterLogic.UpdateCounter(counter);
		//update cache
		User u = new UserLogic(req,resp).GetUser(userId);
		new UserLogic(req,resp).UpdateUser(u);
		SharedCache.setSharedCache("LoginLogic.GetUser."+userId,u,86400);
		User result = new User();
		result.setEntity(u.getEntity());
		
		HashMap<String, Object> data = new HashMap<String, Object>();
		String pageType = (String)session.getAttribute("pageType");
		data.put("pageType", pageType);
		if(pageType.equals("P")){
			data.put("workArea",new POSLogic(req, resp).GetPOS((Long)session.getAttribute("workArea")));
		}
		Gson gson = new Gson();
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(data));
	}
	
	private void Getlogin(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{
		HttpSession session=req.getSession(true);
		long hotelId = (Long) session.getAttribute("hotelId");
		long offset = Long.parseLong(req.getParameter("offset"));
		long line = Long.parseLong(req.getParameter("line"));
		long pointer = Long.parseLong(req.getParameter("pagePointer"));
		LoginLogic loginLogic = new LoginLogic(req,resp);
		List<UserMappingHotel> obj = loginLogic.GetAllUserMapLimit(hotelId,offset,line);
		List<HashMap<String,Object>> userSetObject = new ArrayList<HashMap<String,Object>>();
		for(int i =0;i<obj.size();i++){
			HashMap<String,Object> userSet = new HashMap<String,Object>();
			User user = loginLogic.GetUserWithCache(Long.parseLong(obj.get(i).getUserString()));
			if(user.getCounterId()!=null){
				Counter c = new CounterLogic().GetCounter(Long.parseLong(user.getCounterId()));
				userSet.put("id",user.getId());
				userSet.put("firstName",user.getFirstName());
				userSet.put("email",user.getEmail());
				userSet.put("counterUser",c.getTitle());
				userSet.put("lastStay",user.getLastStay());
				userSetObject.add(userSet);
			}
		}
		double dataSize = loginLogic.GetAllUser(hotelId).size();
		List<Object> rsObj = Arrays.asList(dataSize,pointer,line,userSetObject);
		Gson gson = new Gson();
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(rsObj));
	}
	
	private void Logout(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException, EntityNotFoundException
	{	
		HttpSession session=req.getSession(true);
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userId = (Long) session.getAttribute("userid");
		new LoginLogic(req,resp).Logout(hotelId,userId);
		SharedCache.clearSharedCache("LoginLogic.GetUser."+userId);
		resp.getWriter().println(true);
	}
	
	private void LogoutById(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException, EntityNotFoundException
	{	
		HttpSession session=req.getSession(true);
		Long hotelId = (Long)session.getAttribute("hotelId");
		String userId = req.getParameter("userId");
		String[] arrayUserId = userId.split(",");
		for(int i =0;i<arrayUserId.length;i++){
			new LoginLogic(req,resp).Logout(hotelId,Long.parseLong(arrayUserId[i]));
			SharedCache.clearSharedCache("LoginLogic.GetUser."+Long.parseLong(arrayUserId[i]));
		}
		resp.getWriter().println(true);
	}
	
	private void ChangeStatusLoggedIn(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, EntityNotFoundException
	{	
		HttpSession session=req.getSession(true);
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userId = Long.parseLong(req.getParameter("userId"));
		Object obj = new LoginLogic(req,resp).Logout(hotelId,userId);;
		Gson gson = new Gson();
		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(obj));
	}
	
	private void LoadWorkArea(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		HttpSession session=req.getSession(true);
		
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userid = (Long)session.getAttribute("userid");
		
		UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(hotelId, String.valueOf(userid));
		String defaultArea = s1.getUserlevel().getDefaultWorkAreasString();
		List<POS> areaList = s1.getUserlevel().getWorkAreas();	
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		
		hashresult.put("data", areaList);
		hashresult.put("adminAllowed", s1.getUserlevel().isAdminAllowed());
		hashresult.put("housekeepingAllowed", s1.getUserlevel().isHousekeepingAllowed());
		hashresult.put("defaultWorkArea", defaultArea);
		
		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}
	
	private void LoadDataAndCounter(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		HttpSession session=req.getSession(true);
		
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userid = (Long)session.getAttribute("userid");
		
		UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(hotelId, String.valueOf(userid));
		String defaultCounter = s1.getUserlevel().getDefaultWorkAreas().getDefaultCounterString();
		List<Counter> counterList = new CounterLogic().GetAllCounter(hotelId);
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		
		hashresult.put("data", counterList);
		hashresult.put("defaultCounter", defaultCounter);
		hashresult.put("user", new UserLogic(req, resp).UserDataForChoseWorkAreaPage());
		
		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}
	
	private void LoadDataAndWorkArea(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{		
		HttpSession session=req.getSession(true);
		
		Long hotelId = (Long)session.getAttribute("hotelId");
		long userid = (Long)session.getAttribute("userid");
		
		UserMappingHotel s1 = new UserMappingHotelLogic(req,resp).GetUserMapping(hotelId, String.valueOf(userid));
		String defaultArea = s1.getUserlevel().getDefaultWorkAreasString();
		List<POS> areaList = s1.getUserlevel().getWorkAreas();
		HashMap<String, Object> hashresult = new HashMap<String,Object>();
		
		hashresult.put("data", areaList);
		hashresult.put("adminAllowed", s1.getUserlevel().isAdminAllowed());
		hashresult.put("housekeepingAllowed", s1.getUserlevel().isHousekeepingAllowed());
		hashresult.put("defaultWorkArea", defaultArea);
		hashresult.put("user", new UserLogic(req, resp).UserDataForChoseWorkAreaPage());
		
		Gson gson = new Gson();

		resp.setContentType("text/plain; charset=UTF-8");
		resp.getWriter().println(gson.toJson(hashresult));
	}
	
	public void SaveSessionAndLoadCounter(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{
		HttpSession session=req.getSession(true);
		
		String pageType = req.getParameter("pType");
		session.setAttribute("pageType",pageType);
		
		if(!req.getParameter("id").equals("")){
			long id = Long.parseLong(req.getParameter("id"));
			session.setAttribute("workArea",id);
		}else{
			session.setAttribute("workArea",(long)0);
		}
		
		LoadCounter(req, resp);
	}
	
	public void DeleteSession(HttpServletRequest req, HttpServletResponse resp) throws IOException, JSONException, ServletException, ParseException
	{
		HttpSession session=req.getSession(true);
		session.removeAttribute("pageType");
		session.removeAttribute("workArea");
		
		LoadWorkArea(req, resp);
	}
}

